﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WebCam.Data.WebCamWorker;
using System.Drawing;
using System.Drawing.Imaging;

namespace WebCam.Logic.Detectors
{
    public class LightsaberEventArgs : WorkerComletedEventArgs
    {
        public LightsaberEventArgs(Bitmap bmp, double a, double b, int startX, int startY)
            : base(bmp)
        {
            A = a;
            B = b;
            StartX = startX;
            StartY = startY;
        }

        public double A { get; private set; }
        public double B { get; private set; }
        public int StartX { get; private set; }
        public int StartY { get; private set; }
    }

    public class LightsaberDetector : IWorker 
    {
        private Rectangle rect;
        //private int delta = 70;
        private int step = 2;

        //private Color saberColor = Color.FromArgb(120, 255, 120);

        public void ProcessBitmap(System.Drawing.Bitmap image)
        {
            rect = new Rectangle(0, 0, image.Width, image.Height);
            Bitmap tmp = (Bitmap)image.Clone();

            BitmapData imageData = image.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            BitmapData tmpData = tmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            List<Point> saberPoints = new List<Point>();

            unsafe
            {
                byte* pImage = (byte*)imageData.Scan0.ToPointer();
                byte* pTmpImage = (byte*)tmpData.Scan0.ToPointer();

                for (int j = 0; j < image.Height; j += step)
                {
                    for (int i = 0; i < image.Width; i += step)
                    {
                        byte b = *pImage;
                        byte g = *(pImage + 1);
                        byte r = *(pImage + 2);

                        if (g > 240 && r > 240 && b > 240)
                        {
                            *(pTmpImage) = 0;
                            *(pTmpImage + 1) = 0;
                            *(pTmpImage + 2) = 255;
                            saberPoints.Add(new Point(i, j));
                        }

                        pImage += 3 * step;
                        pTmpImage += 3 * step;
                    }
                    pImage += 3 * image.Width * (step - 1);
                    pTmpImage += 3 * image.Width * (step - 1);
                }
            }

            image.UnlockBits(imageData);
            tmp.UnlockBits(tmpData);

            double Sxy = 0;
            double Sx = 0;
            double Sy = 0;
            double Sx2 = 0;
            int n = saberPoints.Count;

            double ka = 0, kb = 0;
            int startX = 0, startY = 0;
            if (n > 100)
            {
                startX = saberPoints.Max(p => p.X);
                startY = saberPoints.Max(p => p.Y);

                foreach (var point in saberPoints)
                {
                    int X = point.X - startX;
                    int Y = point.Y - startX;

                    Sxy += X * Y;
                    Sx += X;
                    Sy += Y;
                    Sx2 += X * X;
                }

                double Z = n * Sx2 - Sx * Sx;
                kb = (Sy * Sx2 - Sxy * Sx) / Z;
                ka = (n * Sxy - Sx*Sy) / Z;
                //ka = (n * Sxy - Sx * Sy) / (n * Sx2 - Sx * Sx);
                //kb = (Sy - ka * Sx) / n;
                // мы работаем только в 1 координатной четверти
                //startX = saberPoints.Max(p => p.X);
                //startY = saberPoints.Max(p => p.Y);
            }

            if (OnWorkerComplete != null)
            {
                OnWorkerComplete(this, new LightsaberEventArgs(tmp, ka, kb, startX, startY));
            }
        }

        public event WorkerComplete OnWorkerComplete;
    }
}
